Vegetative cooling, or using plants to shield urban environments from the sun’s radiation, has been somewhat of a hot topic in recent years. While there has been ample research on the hyper-local effect to reduce or even eliminate heat islands, our research focuses on the question of whether or not we can identify the effect of the efforts of urban vegetative cooling in the city of Zurich on a larger scale. Furthermore, we investigate if there is any correlation with different factors in regards to air quality.
We would like to prove that the planting of trees and the development of green spaces in an urban environment have positive correlations with the development of air quality indicators and a negative impact on temperatures in the city of Zurich. This project will try to pinpoint the effect trees have on these indicators. The results will be presented in a way to inform politicians, urban developers as well as the public about the impact that a more green city could have on our everyday lives. While there are a number of potential factors, both local and national/global, can have a significant impact on the climate and for this research we are choosing to focus on data from Zürich in regards to air quality, temperature information and the tree inventory. Further factors are described using sources, but are not included in the data analysis. To clarify our project goal and narrow it down we drew the following picture:
Target Picture
It shows two potential futures for Zürich. One with more green spaces and one with more urban wasteland. The idea of the project is to find out how much the trees and green spaces actually impact the city of Zürich in regard to temperature and air pollution.
Scope & limitations Our data sets are limited to the trees planted by garden and forestation services of the municipality of Zurich, and only include roadside and park trees. The effect of local de- or reforestation thus cannot be accounted for. Furthermore, temperature data was taken from roadside stations that could themselves potentially be located within heat islands. Furthermore, as our analysis moves beyond a micro-scale, there are many more factors that we cannot control for, both on the local and macro-environmental level. A factor that we did not control for, which could have large implications on the macro scale of temperature, is the potential disappearance of undeveloped land and urban expansion. Additionally, an analysis of building materials used was also out of the scope of this analysis. To visualize the scope and limitations of our project, we have created a systems view that can be seen below.
Systems View
To ensure we include all potential stakeholders in our project at the appropriate level we create the following stakeholder map:
Stakeholders
We sorted them into three possible categories: “direct”, “indirect”, “unintended”. Our main target is to work together with Grüne Stadt Zürich an convince the politicians, the goverment and urban planners on the benefits of a greener city.
The SDGs lay out the goals that the global community (United Nations
General Assembly in 2015) has agreed on. Total there are 17 goals and
they range from 1. No poverty to 17. Partnerships for the goals and
include social, economic and environmental targets. For the research we
have identified the relevant goals and put them into the three different
categories: Risk, Opportunity and Intended. As can be seen the intended
target for our research is to help achieve the goal number 3. Good
health and well being. This can be achieved if we can prove a
correlation between the amount of trees in a region and an improvement
in air quality, which could then lead to increase of planting of new
trees in Zürich as well as a reduction of concrete wastelands in favor
of green spaces. There are a number opportunities as well in regards to
climate action, economic growth and affordable and clean energy. The are
only limited risks that this project has. However it is imaginable that
the improvement in air quality in certain areas could lead to a increase
in inequalities between the rich and poor. It is also important to
always be responsible and think of possible unintended consequences
while planning for new green zones and planting new trees.
For the research there are three different data sets needed: Air quality information, temperature data, and a tree cadastre. All of these three data sets are publicly available. Following is a quick overview over the different data sets:
Format: csv
Number of rows: 283’763
Number of variables: 8 (most important: date, location, type of
measurement, value)
Source: https://data.stadt-zuerich.ch/dataset/ugz_luftschadstoffmessung_stundenwerte
Format: csv
Number of rows: 4’747
Number of variables: 17 (most important: date, temperature,
location)
Source: https://opendata.swiss/de/dataset/taglich-aktualisierte-meteodaten-seit-1992
Format: csv
Number of rows: 36’239
Number of variables: 17 (most important: year of planting, diameter of
crown, district)
Source: https://data.stadt-zuerich.ch/dataset/geo_baumkataster
The following libraries were used to analyse the data:
In this step we collected the three data sets and prepared them so that they are for use in the analysis. To achieve this, certain changes to the data were necessary to facilitate an informative analysis.
First we loaded the tree cadastre data and wrangled the data to get additional information such as the amount of trees per year and the number of trees by district.
d.trees <- read.csv('../datasets/gsz.baumkataster_baumstandorte.csv', encoding = "UTF-8")
names(d.trees)[1] <- "objid"
#head(trees)
#str(trees)
#Wrangling and mutating tree data
# trees by year
tree_ts <- d.trees %>%
dplyr::select(pflanzjahr) %>%
filter(pflanzjahr > 1980) %>%
group_by(pflanzjahr) %>%
summarise(count = n())
# Trees by district
tree_quartier <- d.trees %>%
dplyr::select(pflanzjahr, objid, quartier) %>%
filter(pflanzjahr > 1980) %>%
group_by(pflanzjahr, quartier) %>%
summarise(count = n())
## `summarise()` has grouped output by 'pflanzjahr'. You can override using the
## `.groups` argument.
# sum of trees
tree_ts_sum <- tree_ts %>%
mutate(sum_trees = cumsum(count))
# Trees by district, year
tree_quartier_year_full <- d.trees %>%
dplyr::select(pflanzjahr, quartier, kronendurchmesser) %>%
filter(pflanzjahr > 1980) %>%
group_by(pflanzjahr, quartier) %>%
summarise(count = n(), sum_crown = sum(kronendurchmesser))
## `summarise()` has grouped output by 'pflanzjahr'. You can override using the
## `.groups` argument.
# trees by year
tree_year <- d.trees %>%
dplyr::select(pflanzjahr, kronendurchmesser) %>%
filter(pflanzjahr > 1980) %>%
group_by(pflanzjahr) %>%
summarise(tree_count = n(), crown_sum = sum(kronendurchmesser))
tree_year_sum <- tree_year %>%
mutate(cum_trees = cumsum(tree_count)) %>%
mutate(cum_crown = cumsum(crown_sum))
Next we load all the temperature information from the meteo data set. While this data set includes other information such as rain duration we will only use the temperature, as it seems unlikely that the amount of trees significantly impact the rain fall in an area.
filenames.meteo <- list.files(path = "../datasets/meteo/", pattern = "*.csv", full.names = TRUE)
data_list.meteo <- lapply(filenames.meteo, read.csv)
# Combine the data frames in the list into a single data frame
meteo <- do.call(rbind, data_list.meteo)
names(meteo)[1] <- "Date"
meteo$Date <- format(as.Date(meteo$Date), format = "%Y-%m-%d")
# Datensatz mit Temperatur und Globalstrahlung pro Messstation
meteo.extr <- meteo %>%
filter(Parameter == "T" | Parameter == "StrGlo" | Parameter =="T_max_h1")
meteo.extr$Jahr <- year(meteo.extr$Date)
# weiter mit "normalem" Meteodatensatz
meteo <- meteo[meteo$Standort=="Zch_Stampfenbachstrasse",]
meteo <- meteo %>%
select(c("Date","Parameter","Wert")) %>%
pivot_wider(id_cols = "Date",names_from = "Parameter",values_from = "Wert") %>%
select(c("Date","T","RainDur","p"))
meteo$Date <- ymd(meteo$Date)
head(meteo)
Lastly the air quality data is loaded. While there are multiple location were air quality was measured not every station measured each variable. They also were not all built at the same time.
filenames.air <- list.files(path = "../datasets/air/", pattern = "*.csv", full.names = TRUE)
data_list.air <- lapply(filenames.air, read.csv)
# Combine the data frames in the list into a single data frame
air <- do.call(rbind, data_list.air)
names(air)[1] <- "Date"
air$Date <- as.Date(format(air$Date), "%Y-%m-%d")
# add column Jahr
air$Jahr <- as.numeric(format(air$Date,'%Y'))
head(air)
air.wide <- air %>%
filter(Standort == "Zch_Stampfenbachstrasse") %>%
select(c("Date", "Parameter", "Wert")) %>%
pivot_wider(id_cols = "Date", names_from = "Parameter", values_from = "Wert")
air.short <- air[air$Standort=="Zch_Stampfenbachstrasse",]
air.short <- air.short %>%
select(c("Date", "Parameter", "Wert")) %>%
pivot_wider(id_cols = "Date",names_from = "Parameter",values_from = "Wert")
keep <- c("Date", "CO", "NOx")
air.short <- air.short[keep]
keep <- c("Date", "CO")
air.co <- air.short[keep]
keep <- c("Date", "NOx")
air.NOx <- air.short[keep]
#air.NOx <- air["NOx"] <- log(air["NOx"])
To gain insights from the available information we have created a number of graphics. These already show preliminary results of our project.
#melt data frame into long format
air.plot <- melt(air.co, id.vars = "Date")
#create line plot for each column in data frame
ggplot(air.plot, aes(Date, value), group = 5) +
geom_line(aes(colour = variable))
air.means = air %>%
filter(!is.na(Wert)) %>%
group_by(Parameter, Jahr) %>%
summarize(Mean = round(mean(Wert),2),
.groups = "drop")
The following graphs show the development over time for some specific air pollutants as of 1983.
Fig. nnn: Carbon monoxide and particulate matter
Figure nnn above on the left hand shows the mean amount of carbon monoxide per year as of 1983. The average could be reduced to a large extent until 1990, but we couldn’t find a explanation in the internet to which we could refer, as most time series only start as of 1990. We assume that this is - besides other potential influencing factors - a direct impact of the implementation of catalysts in the cars, which should reduce carbon monoxide, hydrocarbon and nitrogen oxyds. The two graphs on the right side show two different sizes of particulate matter, for which we only have data as of 2017 for the very small particulate matter PM2.5. We can observe in the two graphs an improvement over the years as well.
plot(subset(air.means, Parameter == "NO",
c(Jahr, Mean)), type = "l",
main = "Mean of NO per Year [µg/m3]")
plot(subset(air.means, Parameter == "NO2",
c(Jahr, Mean)), type = "l",
main = "Mean of NO2 per Year [µg/m3]")
plot(subset(air.means, Parameter == "NOx",
c(Jahr, Mean)), type = "l",
main = "Mean of NOx per Year [ppb]")
#nrow(air[air.means$Parameter == "NO" & air.means$Jahr == "2008"])
#nrow(air[air.means$Parameter == "NO" & air.means$Jahr == "2009"])
#nrow(subset(air.means,sCode == "CA"))
Nitric Oxide Nitrogen dioxide Nitrogen oxides
One can see that the both the “NOx” and the “CO” graph show that the air quality has improved significantly since 1980. It is unlikely to say the least that trees are the only factor in this improvement. More likely other factors such as new laws and regulations in regards to catalysts of cars are more likely the major factor.
# Boxplots for CO all over Zürich
boxplot(Wert ~ Jahr, data = air, subset = Parameter %in% names(table("CO")),
main= "CO in Zürich (Stampfenbachstrasse) per Year [mg/m3]",
xlab = "Year", ylab = "mg/m3")
boxplot(Wert ~ Jahr, data = air, subset = Parameter %in% names(table("NOx")),
main= "NOx in Zürich per Year [ppb]",
xlab = "Year", ylab = "ppb")
# Boxplots for NOx per monitoring station
#air.he <- air %>% filter(Standort == "Zch_Heubeeribüel")
air.ro <- air %>% filter(Standort == "Zch_Rosengartenstrasse")
air.sc <- air %>% filter(Standort == "Zch_Schimmelstrasse")
air.st <- air %>% filter(Standort == "Zch_Stampfenbachstrasse")
# boxplot(Wert ~ Jahr, data = air.he, subset = Parameter %in% names(table("NOx")),
# main= "NOx at Heubeeribuel per Year [ppb]",
# xlab = "Year", ylab = "ppb")
boxplot(Wert ~ Jahr, data = air.ro, subset = Parameter %in% names(table("NOx")),
main= "NOx at Rosengartenstrasse per Year [ppb]",
xlab = "Year", ylab = "ppb")
boxplot(Wert ~ Jahr, data = air.sc, subset = Parameter %in% names(table("NOx")),
main= "NOx at Schimmelstrasse per Year [ppb]",
xlab = "Year", ylab = "ppb")
boxplot(Wert ~ Jahr, data = air.st, subset = Parameter %in% names(table("NOx")),
main= "NOx at Stampfenbachstrasse per Year [ppb]",
xlab = "Year", ylab = "ppb")
# bar chart pflanzjahr alle
ggplot(d.trees, aes(x = pflanzjahr)) +
geom_bar() +
labs(title="Trees per year planted")
## Warning: Removed 13987 rows containing non-finite values (`stat_count()`).
# bar chart nur neuere pflanzjahre
ggplot(d.trees[trees$pflanzjahr > 1949, ], aes(x = pflanzjahr)) +
geom_bar() +
labs(title="Trees planted as of 1950")
# bar chart kronendurchmesser
ggplot(d.trees, aes(x = kronendurchmesser)) +
geom_bar() +
labs(title="Number of trees per crown diameter")
As one can see there is a trend to planting more trees in Zürich.
However, there are also quite a few outliers visible in the graph. These
outliers can usually be explained quite easily with replanting efforts.
For example in 2000 a larger number of trees than normal were planted as
replacements for all the trees that were blown down or had to be cut
down because of cyclone Lothar in December of 1999.
Having gained an overview of the data, we would now like to analyse the data in more detail using a few different methodologies.
In this section we are trying to see if there is a correlation over time between the amount of trees and the air quality or temperature. For this we use timeseries analysis, meaning we need to convert our data into timeseries objects. After transforming them we can then look at the decomposition of the objects. Thus we are able to see trends, seasonality and residuals. However the seasonality is only visible for air pollution and temperature, as the tree information is only available on a yearly basis.
meteo %<>% complete(Date=seq.Date(min(Date), max(Date), by='day'))
# Use the time series class of the library stats
freq_daily <- 365.2422
temp <-
ts(meteo$T, start=c(year(min(meteo$Date)),yday(min(meteo$Date))),
frequency=freq_daily) %>%
na_replace(fill=0)
# Stationarity test and decomposition
# adf.test(temp,k=0)
temp_comp=decompose(temp)
plot(temp_comp)
title(sub = "Temperature")
# Manual decomposition
meteo %<>% mutate(year=year(meteo$Date)+yday(meteo$Date)/freq_daily)
temp_trend <- lm(meteo$T~meteo$year)
plot(temp, main="Temperature trend per year")
abline(temp_trend)
# Prepare yearly data
meteo_yr <- meteo %>%
mutate(temp_raw=replace_na(T,0)) %>%
group_by(Year=year(Date)) %>%
filter(Year>=1980 & Year<=2021) %>%
summarize(temp=mean(temp_raw)) %>%
ungroup()
temp_yr <- ts(temp, start=min(meteo_yr$Year))
tb_temp_ts <- tbats(temp_yr)
# Differ
## twice-difference the CO2 data
temp_d2 <- diff(temp, differences = 1)
## plot the differenced data
# plot(temp_d2, ylab = "Temperature without trend")
## difference the differenced CO2 data
temp_d2d12 <- diff(temp_d2, lag = 12)
## plot the newly differenced data
plot(temp_d2d12, ylab = "Temperature without trend and seasonality")
Generally we can see that the temperature is slightly rising over time.
There is a slight upwards trend noticeable and it is also important to
remember how much danger a temperature increase of just one percent can
be for the biodiversity.
air.short %<>% complete(Date=seq.Date(min(Date), max(Date), by='day'))
# Use the time series class of the library stats
freq_daily <- 365.2422
co <-
ts(air.short$CO, start=c(year(min(air.short$Date)),yday(min(air.short$Date))),
frequency=freq_daily) %>%
na_replace(fill=0)
NOx <-
ts(air.short$NOx, start=c(year(min(air.short$Date)), yday(min(air.short$Date))),
frequency=freq_daily) %>%
na_replace(fill=0)
# Stationarity test and decomposition
# adf.test(co,k=0)
# adf.test(NOx,k=0)
co_comp=decompose(co)
NOx_comp=decompose(NOx)
# plot(co_comp)
# title(sub = "CO")
# plot(NOx_comp)
# title(sub = "NOx")
# Manual decomposition
air.short %<>% mutate(year=year(air.short$Date)+yday(air.short$Date)/freq_daily)
co_trend <- lm(air.short$CO~air.short$year)
NOx_trend <- lm(air.short$NOx~air.short$year)
# plot(co, main="CO trend per year")
# abline(co_trend)
# plot(NOx, main="NOx trend per year")
# abline(NOx_trend)
air_yr <- air.short %>%
mutate(co_raw=replace_na(CO,0), NOx_raw=replace_na(NOx,0)) %>%
group_by(Year=year(Date)) %>%
filter(Year>=1980 & Year<=2021) %>%
summarize(co=sum(co_raw), NOx=mean(NOx_raw)) %>%
ungroup()
# Time series
co_yr <- ts(air_yr$co, start=min(air_yr$Year), frequency=1)
NOx_yr <- ts(air_yr$NOx, start=min(air_yr$Year), frequency=1)
# plot(co_yr)
# plot(NOx_yr)
# Manual decomposition
co_yr_trend <- lm(air_yr$co~air_yr$Year)
plot(co_yr, xlab='Year', ylab='Average co pollution')
abline(co_yr_trend)
title(main = "CO development over the years and trend line")
NOx_yr_trend <- lm(air_yr$NOx~air_yr$Year)
plot(NOx_yr, xlab='Year', ylab='Average NOx pollution')
abline(NOx_yr_trend)
title(main = "NOx development over the years and trend line")
# plot(co_yr)
# pacf(co_yr)
# plot(tbats(co_yr))
# title(sub = "CO ")
tree_ts <- ts(tree_ts_sum$sum_trees, start=min(tree_ts_sum$pflanzjahr), frequency=1)
tb_tree_ts <- tbats(tree_ts)
tb_co_ts <- tbats(co_yr)
tb_nox_ts <- tbats(NOx_yr)
plot(residuals(tb_co_ts))
title(main = "Residuals of CO")
plot(residuals(tb_nox_ts))
title(main = "Residuals of NOx")
# adf.test(co_yr)
# "Forecast"
# plot(forecast(co_yr))
The timeseries analysis of Carbon monoxide (co) and Nitrogen oxide (NOx) show that the they are closely correlated. It is further clear that they have both decreased drastically since the 1980 in Zürich. It is unlikely that the whole change can be attributed to the growing number of trees and green spaces in Zürich. It is more likely that a variety of factors including advancement in technologies and changes in laws and regulations contributed as well to the improvement in air quality.
# Make the time series comparable
temp_comp_random <- data.frame(Date=time(temp_comp$random), Random=temp_comp$random)
co_comp_random <- data.frame(Date=time(co_comp$random), Random=co_comp$random)
NOx_comp_random <- data.frame(Date=time(NOx_comp$random), Random=NOx_comp$random)
#trees_comp_random <- data.frame(Date=time(trees_comp$random), Random=trees_comp$random)
window <- list(start=1980,end=2021)
temp_comp_random %<>% filter(Date>=window$start&Date<window$end)
co_comp_random %<>% filter(Date>=window$start&Date<window$end)
NOx_comp_random %<>% filter(Date>=window$start&Date<window$end)
#trees_comp_random %<>% filter(Date>=window$start&Date<window$end)
temp_comp_random_ts <- ts(temp_comp_random$Random, start=c(window$start,1), frequency=freq_daily)
co_comp_random_ts <- ts(co_comp_random$Random, start=c(window$start,1), frequency=freq_daily)
NOx_comp_random_ts <- ts(NOx_comp_random$Random, start=c(window$start,1), frequency=freq_daily)
#trees_comp_random_ts <- ts(trees_comp_random$Random, start=c(window$start,1), frequency=freq_daily)
# Cross correlation function
# ccf(temp_comp_random_ts,co_comp_random_ts)
# ccf(temp_comp_random_ts, co_comp_random_ts,
# lag.max = 300,
# main = "Temp - CO Cross-Correlation Plot",
# ylab = "CCF",
# na.action = na.pass)
ccf(residuals(tb_tree_ts), residuals(tb_nox_ts),
lag.max = 300,
main = "Trees - NOx Cross-Correlation Plot",
ylab = "CCF")
ccf(residuals(tb_tree_ts), residuals(tb_co_ts),
lag.max = 300,
main = "Trees - CO Cross-Correlation Plot",
ylab = "CCF")
ccf(residuals(tb_tree_ts), residuals(tb_temp_ts),
lag.max = 300,
main = "Trees - Temperature Cross-Correlation Plot",
ylab = "CCF")
Now one can see the correlations between the sum of trees and air quality (CO and NOx) as well as the correlation between the sum of trees and temperature. The graphs shows no strong correlations, although a slightly significant correlation with a lag is visible for amount of trees on air quality. Meaning that after a some time a larger amount of trees could have an influence in reducing Carbon monoxide and Nitrogen oxide in the air.
# Stampfenbach max of mean of daily temperature with trendline
meteo.sta <- meteo.extr %>%
filter(Standort == "Zch_Stampfenbachstrasse") %>%
filter(Parameter == "T") %>%
group_by(Jahr, Parameter) %>%
summarize(Max = max(Wert, na.rm = TRUE), .groups = "drop")
ggplot(meteo.sta, aes(x = Jahr, y = Max)) +
geom_line() +
ggtitle("Development of maximum of mean temperature at Stampfenbachstrasse") +
geom_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula = 'y ~ x'
Fig. 1: temperature trends
# Stampfenbach min of mean of daily temperature with trendline
meteo.sta.min <- meteo.extr %>%
filter(Standort == "Zch_Stampfenbachstrasse") %>%
filter(Parameter == "T") %>%
group_by(Jahr, Parameter) %>%
summarize(Min = min(Wert, na.rm = TRUE), .groups = "drop")
ggplot(meteo.sta.min, aes(x = Jahr, y = Min)) +
geom_line() +
ggtitle("Development of minimum of mean temperature at Stampfenbachstrasse") +
geom_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula = 'y ~ x'
Fig. 1: temperature trends
The left graph in Fig. nn shows the yearly development of the max of the daily means .
###
# Stampfenbach max of max temperature with trendline
meteo.sta.max <- meteo.extr %>%
filter(Standort == "Zch_Stampfenbachstrasse") %>%
filter(Parameter == "T_max_h1") %>%
group_by(Jahr, Parameter) %>%
summarize(Max = max(Wert, na.rm = TRUE), .groups = "drop")
ggplot(meteo.sta.max, aes(x = Jahr, y = Max)) +
geom_line() +
ggtitle("Development of maximum daily temperature at Stampfenbachstrasse") +
geom_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula = 'y ~ x'
Fig. 1: Text
summary(lm(meteo.sta$Max ~ meteo.sta$Jahr))
##
## Call:
## lm(formula = meteo.sta$Max ~ meteo.sta$Jahr)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.1813 -0.8598 -0.1605 0.9159 2.4001
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -125.76239 52.85228 -2.380 0.0241 *
## meteo.sta$Jahr 0.07629 0.02633 2.897 0.0071 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.311 on 29 degrees of freedom
## Multiple R-squared: 0.2244, Adjusted R-squared: 0.1977
## F-statistic: 8.392 on 1 and 29 DF, p-value: 0.0071
summary(lm(meteo.sta.min$Min ~ meteo.sta.min$Jahr))
##
## Call:
## lm(formula = meteo.sta.min$Min ~ meteo.sta.min$Jahr)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.6680 -1.3115 0.0823 1.6938 3.5812
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -224.49694 94.83822 -2.367 0.0248 *
## meteo.sta.min$Jahr 0.10896 0.04725 2.306 0.0285 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.353 on 29 degrees of freedom
## Multiple R-squared: 0.1549, Adjusted R-squared: 0.1258
## F-statistic: 5.317 on 1 and 29 DF, p-value: 0.02846
summary(lm(meteo.sta.max$Max ~ meteo.sta.max$Jahr))
##
## Call:
## lm(formula = meteo.sta.max$Max ~ meteo.sta.max$Jahr)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.0211 -0.9956 0.2307 0.9391 3.1013
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -116.29672 55.29212 -2.103 0.0442 *
## meteo.sta.max$Jahr 0.07460 0.02755 2.708 0.0112 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.372 on 29 degrees of freedom
## Multiple R-squared: 0.2018, Adjusted R-squared: 0.1743
## F-statistic: 7.333 on 1 and 29 DF, p-value: 0.01124
# Stampfenbach mean of Globalstrahlung with trendline
meteo.sta.glo <- meteo.extr %>%
filter(Standort == "Zch_Stampfenbachstrasse") %>%
filter(Parameter == "StrGlo") %>%
group_by(Jahr, Parameter) %>%
summarize(Max = max(Wert, na.rm = TRUE), .groups = "drop")
ggplot(meteo.sta.glo, aes(x = Jahr, y = Max)) +
geom_line() +
ggtitle("Development of mean of global radiation at Stampfenbachstrasse") +
geom_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula = 'y ~ x'
summary(lm(meteo.sta.glo$Max ~ meteo.sta.glo$Jahr))
##
## Call:
## lm(formula = meteo.sta.glo$Max ~ meteo.sta.glo$Jahr)
##
## Residuals:
## Min 1Q Median 3Q Max
## -301.444 -2.835 20.195 29.017 36.210
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -3733.156 2644.934 -1.411 0.169
## meteo.sta.glo$Jahr 2.015 1.318 1.529 0.137
##
## Residual standard error: 65.63 on 29 degrees of freedom
## Multiple R-squared: 0.07462, Adjusted R-squared: 0.04271
## F-statistic: 2.339 on 1 and 29 DF, p-value: 0.137
To aid us in our geospatial analysis and to potentially communicate some of our findings to a broader public, we have created a Tableau dashboard. Below you can find a screenshot of one of the visualizations in our dashboard. To explore the full interactive dashboard, please follow the following link.
For the dashboard, some additional data wrangling was done. Furthermore
the dataset had to be expanded and missing values needed to be added to
create a smoother dashboard experience.
## `summarise()` has grouped output by 'pflanzjahr'. You can override using the
## `.groups` argument.
## `summarise()` has grouped output by 'pflanzjahr'. You can override using the
## `.groups` argument.
## `summarise()` has grouped output by 'pflanzjahr'. You can override using the
## `.groups` argument.
## [1] 1981 1981 1981 1981 1981 1981 1981 1981 1981 1981 1981 1981 1982 1982
## [15] 1982 1982 1982 1982 1982 1982 1982 1982 1982 1982 1982 1983 1983 1983
## [29] 1983 1983 1984 1984 1984 1984 1984 1984 1984 1984 1984 1984 1984 1984
## [43] 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985
## [57] 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985
## [71] 1985 1985 1985 1985 1986 1986 1986 1986 1986 1986 1986 1986 1986 1986
## [85] 1986 1986 1986 1987 1987 1987 1987 1987 1987 1987 1987 1987 1987 1987
## [99] 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988
## [113] 1988 1988 1988 1988 1988 1988 1989 1989 1989 1989 1989 1989 1989 1989
## [127] 1989 1989 1989 1989 1989 1989 1990 1990 1990 1990 1990 1990 1990 1990
## [141] 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990
## [155] 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 1991 1991
## [169] 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991
## [183] 1991 1991 1991 1991 1991 1991 1991 1992 1992 1992 1992 1992 1992 1992
## [197] 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992
## [211] 1992 1992 1993 1993 1993 1993 1993 1993 1993 1993 1993 1993 1993 1993
## [225] 1993 1993 1993 1993 1993 1993 1993 1994 1994 1994 1994 1994 1994 1994
## [239] 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994
## [253] 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995
## [267] 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995
## [281] 1995 1995 1995 1995 1995 1996 1996 1996 1996 1996 1996 1996 1996 1996
## [295] 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996
## [309] 1996 1996 1996 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997
## [323] 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997
## [337] 1997 1997 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998
## [351] 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998
## [365] 1998 1998 1999 1999 1999 1999 1999 1999 1999 1999 1999 1999 1999 1999
## [379] 1999 1999 1999 1999 1999 1999 1999 1999 1999 2000 2000 2000 2000 2000
## [393] 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000
## [407] 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000
## [421] 2000 2001 2001 2001 2001 2001 2001 2001 2001 2001 2001 2001 2001 2001
## [435] 2001 2001 2001 2001 2001 2001 2001 2002 2002 2002 2002 2002 2002 2002
## [449] 2002 2002 2002 2002 2002 2002 2002 2002 2002 2002 2002 2002 2002 2002
## [463] 2002 2002 2002 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003
## [477] 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003 2003
## [491] 2003 2003 2003 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004
## [505] 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 2004
## [519] 2004 2004 2004 2004 2004 2004 2004 2004 2005 2005 2005 2005 2005 2005
## [533] 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005
## [547] 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005 2005
## [561] 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006
## [575] 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006 2006
## [589] 2006 2006 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
## [603] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007
## [617] 2007 2007 2007 2007 2007 2007 2007 2008 2008 2008 2008 2008 2008 2008
## [631] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008
## [645] 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2008 2009
## [659] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
## [673] 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009
## [687] 2009 2009 2009 2009 2009 2010 2010 2010 2010 2010 2010 2010 2010 2010
## [701] 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010
## [715] 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2011 2011 2011 2011
## [729] 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011
## [743] 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011
## [757] 2011 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012
## [771] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012
## [785] 2012 2012 2012 2012 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
## [799] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
## [813] 2013 2013 2013 2013 2013 2013 2013 2014 2014 2014 2014 2014 2014 2014
## [827] 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014
## [841] 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2015 2015 2015
## [855] 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015
## [869] 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015
## [883] 2015 2015 2015 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016
## [897] 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 2016
## [911] 2016 2016 2016 2016 2016 2016 2016 2016 2016 2017 2017 2017 2017 2017
## [925] 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017
## [939] 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017
## [953] 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018
## [967] 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018 2018
## [981] 2018 2018 2018 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019
## [995] 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019 2019
## [1009] 2019 2019 2019 2019 2019 2019 2019 2019 2019 2020 2020 2020 2020 2020
## [1023] 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020
## [1037] 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020
## [1051] 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021
## [1065] 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 2021
## [1079] 2021 2021 2021 2021 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022
## [1093] 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022
## [1107] 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 2023 2023 2023 2023
## Rows: 90379 Columns: 7
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (5): Zch_Stampfenbachstrasse, StrGlo, d1, W/m2, bereinigt
## dbl (1): 135.06
## dttm (1): 1992-07-01T00:00+0100
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## `summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
## `summarise()` has grouped output by 'Jahr', 'Standort'. You can override using the `.groups` argument.
Based on our data, there is no correlation between the number of trees planted in a given district in the city of Zurich and the temperature on a macro scale.
While we did manage to get some very insightful and interesting results, we did also come across some issues, mostly with the data availability and quality. It would be useful to collect more data from across the different districts in Zürich. It would also be helpful if that data would be completely available across a time-frame of at least 20 years. This would allow for creating a more complete picture and better comparisons among districts. Another possibility would be take a closer look at some of the outliers using Extreme Value Theory (EVT). A further approach would be to create a simulation. While this would obviously involve a lot more effort, it would allow to simulate potential scenarios and could thus help city planners and politicians to make more informed policy decisions.
Further research questions could take a more micro-scope and evaluate the temperature on both a micro and macro scale. Especially interesting would be an evaluation to calculate or simulate the amount of vegetative cooling to reach a critical mass that makes the efforts observable on a macro level. In our opinion, it would be useful to not only include trees, as our